home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------
-
- 3D2 to DKB File Converter
- Copyright 1991 by Steve Anger
-
- This file may be freely modified and distributed so long as the original
- copyright notice is included.
-
- V1.2 05/09/91 Minor MSC compatibility modifications made by Aaron A. Collins
-
- --------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
- #ifdef __TURBOC__
- #include <alloc.h>
- #include <conio.h>
- #include <graphics.h>
- #endif
-
- const char Ver[] = "v1.2";
-
- #ifndef M_PI
- #define M_PI 3.14159265358979323846
- #endif
-
- typedef struct
- {
- float x, y, z;
- } Vector;
-
-
- typedef struct
- {
- float Red;
- float Green;
- float Blue;
- } Palette;
-
-
- typedef struct
- {
- int VertA; /* Vertex A of the triangle */
- int VertB; /* " B " " " */
- int VertC; /* " C " " " */
- int Colour; /* Colour of triangle */
- int EdgeFlag; /* Which edges are to be drawn (not used) */
- } Triangle;
-
-
- typedef struct TriNode
- {
- int TriNo;
- struct TriNode *Next;
- } TriangleNode;
-
-
- typedef unsigned char byte;
- typedef signed int word;
- typedef int boolean;
- const int true = 1;
- const int false = 0;
-
- /* Function prototype definitions */
- void Read3D2Header(void);
- void Read3D2Object(void);
-
- void WriteDKBHeader(void);
- void WriteDKBObject(void);
- void WriteDKBSummary(void);
-
- void ProcessArgs (int argc, char *argv[]);
- void PrintVector (FILE *g, Vector *V);
- void AddExt (char *FileName, char *Ext, boolean Force);
- byte ReadByte(FILE *f);
- word ReadWord(FILE *f);
- void Abort (char* Msg, int ExitCode);
- void MinVector (Vector *V1, Vector *V2);
- void MaxVector (Vector *V1, Vector *V2);
- void VertNormal (Triangle *T, Vector *NormA, Vector *NormB, Vector *NormC);
- void BuildTriIndex (void);
- void DumpTriIndex (void);
- void TriNormal (Triangle *T, Vector *Normal);
-
- void InitDisplay(void);
- void PlotTriangle (Triangle *Tri);
- void CloseDisplay(void);
-
- void VectAdd (Vector *V1, Vector *V2, Vector *V3);
- void VectSub (Vector *V1, Vector *V2, Vector *V3);
- void VectScale (Vector *V1, float k);
- float VectMag (Vector *V);
- float DotProd (Vector *V1, Vector *V2);
- void CrossProd (Vector *V1, Vector *V2, Vector *V3);
- void VectCopy (Vector *V1, Vector *V2);
- void VectInit (Vector *V, float x, float y, float z);
- float VectAngle (Vector *V1, Vector *V2);
-
- /* Global variables */
- FILE *f; /* Input file */
- FILE *g; /* Output file */
- char InFile[64]; /* Input file name */
- char OutFile[64]; /* Output file name */
- boolean Display; /* Screen preview flag */
- Vector LookAt; /* Location to look at */
- Vector ViewPoint; /* Location of viewpoint */
- Vector Nx, Ny, Nz; /* Co-ord system for rotated space */
- float Smooth; /* Smooth triangles who's normals differ by */
- /* less than this angle (degrees) */
-
- /* 3D2 Header infomation */
- int ObjCount; /* Number of objects contained in file */
- int LightOn[3]; /* 1 = Light source is on, 0 = off */
- float LightBright[3]; /* Light source brightness */
- Vector LightPos[3]; /* Light source position */
- float Ambient; /* Ambient light brightness */
- Palette Pal[16]; /* Colour palette for objects */
- int GBase[16]; /* Colour group base array (not used) */
- int PalType; /* Colour palette type (not used) */
- int WColour; /* Wireframe colour (not used) */
- int OColour; /* Outline colour (not used) */
-
- /* 3D2 Object information */
- char ObjName[9]; /* Name of current object */
- int VertCount; /* Number of verticies in object */
- Vector *Vert; /* Pointer to array of verticies */
- int TriCount; /* Number of triangular faces in object */
- Triangle *Tri; /* Pointer to array of triangles */
- int DegenTri; /* Degenerate triangles */
-
- Vector ObjMin, ObjMax;
- TriangleNode **TriList; /* List of triangles touching each vertex */
-
-
-
- int main (int argc, char* argv[])
- {
- int i;
- int Verticies[40], Triangles[40], Degens[40];
- char Names[40][9];
- int TotalTri, TotalVert, TotalDegen;
-
- ProcessArgs (argc, argv);
-
- if (Display)
- InitDisplay();
-
- Read3D2Header(); /* Read 3D2 file header */
- WriteDKBHeader(); /* Write DKB file header info */
-
- for (i = 0; i < ObjCount; i++) {
- Read3D2Object(); /* Read an object from 3D2 file */
- WriteDKBObject(); /* Write object to DKB file */
-
- strcpy (Names[i], ObjName); /* Keep a list of the object names, */
- Verticies[i] = VertCount; /* vertex counts, etc. */
- Triangles[i] = TriCount;
- Degens[i] = DegenTri;
- }
-
- WriteDKBSummary();
-
- fclose(f);
- fclose(g);
-
- if (Display)
- CloseDisplay();
-
- /* Print summary of objects converted */
- printf ("\nConverted %d object(s), ", ObjCount);
- printf ("%d light source(s).\n\n", LightOn[0] + LightOn[1] + LightOn[2]);
-
- printf (" Object Verticies Triangles Degen Tri \n");
- printf ("---------- ----------- ----------- -----------\n");
-
- TotalVert = 0;
- TotalTri = 0;
- TotalDegen = 0;
-
- for (i = 0; i < ObjCount; i++) {
- printf (" %-8s %6d %6d %6d\n",
- Names[i], Verticies[i], Triangles[i], Degens[i]);
- TotalVert += Verticies[i];
- TotalTri += Triangles[i];
- TotalDegen += Degens[i];
- }
-
- printf (" =========== =========== ===========\n");
- printf (" Total %6d %6d %6d\n", TotalVert, TotalTri, TotalDegen);
-
- return 0;
- }
-
-
- void ProcessArgs (int argc, char *argv[])
- {
- int i;
-
- printf (" 3D2 to DKB Data File Converter %s\n", Ver);
- printf (" Copyright 1991 Steve Anger\n\n");
-
- if (argc < 2) {
- printf ("Usage: 3d2-dkb inputfile [outputfile] [[-/]options]\n\n");
- printf ("Options: -d - Preview object on screen.\n");
- printf (" -lxnnn - Set LOOK_AT x coord to nnn\n");
- printf (" -lynnn - ' ' y ' ' ' \n");
- printf (" -lznnn - ' ' z ' ' ' \n");
- printf (" -vxnnn - Set VIEW_POINT x coord to nnn\n");
- printf (" -vynnn - ' ' y ' ' ' \n");
- printf (" -vznnn - ' ' z ' ' ' \n");
- printf (" -snnn - Smooth triangle boundaries with angles < nnn\n");
- exit(1);
- }
-
- InFile[0] = '\0';
- OutFile[0] = '\0';
- Display = false;
-
- VectInit (&LookAt, 0.0, 0.0, 0.0);
- VectInit (&ViewPoint, 50.0, 50.0, -50.0);
-
- Smooth = 0.0;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-' || argv[i][0] == '/') {
- switch (argv[i][1]) {
- case 'd': Display = true;
- break;
-
- case 's': sscanf (&argv[i][2], "%f", &Smooth);
- break;
-
- case 'l': switch (argv[i][2]) {
- case 'x': sscanf (&argv[i][3], "%f", &LookAt.x);
- break;
- case 'y': sscanf (&argv[i][3], "%f", &LookAt.y);
- break;
- case 'z': sscanf (&argv[i][3], "%f", &LookAt.z);
- }
- break;
-
- case 'v': switch (argv[i][2]) {
- case 'x': sscanf (&argv[i][3], "%f", &ViewPoint.x);
- break;
- case 'y': sscanf (&argv[i][3], "%f", &ViewPoint.y);
- break;
- case 'z': sscanf (&argv[i][3], "%f", &ViewPoint.z);
- }
- }
- }
- else if (InFile[0] == '\0') {
- strcpy (InFile, argv[i]);
- AddExt (InFile, "3D2", false);
- }
- else if (OutFile[0] == '\0') {
- strcpy (OutFile, argv[i]);
- AddExt (OutFile, "DAT", false);
- }
- else
- Abort ("Too many file names.", 1);
- }
-
- /* Prevent a division by zero error later on */
- if ((ViewPoint.x - LookAt.x) == 0.0 && (ViewPoint.z - LookAt.z) == 0.0)
- ViewPoint.z -= 0.01;
-
- if (OutFile[0] == '\0') {
- strcpy (OutFile, InFile);
- AddExt (OutFile, "DAT", true);
- }
-
- f = fopen (InFile, "rb");
- if (f == NULL)
- Abort ("Error opening input file.", 2);
-
- g = fopen (OutFile, "w");
- if (g == NULL)
- Abort ("Error opening output file.", 2);
- }
-
-
- void AddExt (char *FileName, char *Ext, boolean Force)
- {
- int i;
-
- for (i = 0; i < strlen(FileName); i++)
- if (FileName[i] == '.') break;
-
- if (FileName[i] == '\0' || Force) {
- FileName[i] = '.';
- strcpy (&FileName[i+1], Ext);
- }
- }
-
-
- byte ReadByte(FILE *f)
- {
- return fgetc(f);
- }
-
-
- word ReadWord(FILE *f)
- {
- byte bh, bl;
-
- bh = fgetc(f); /* Read a Motorola format word */
- bl = fgetc(f);
-
- return (256*bh + bl);
- }
-
-
- void Abort (char *Msg, int ExitCode)
- {
- if (Display)
- CloseDisplay();
-
- puts (Msg);
- exit (ExitCode);
- }
-
-
- void PrintVector (FILE *g, Vector *V)
- {
- fprintf (g, "<%.2f %.2f %.2f> ", V->x, V->y, V->z);
- }
-
-
- void MinVector (Vector *V1, Vector *V2)
- {
- V1->x = (V1->x < V2->x) ? V1->x : V2->x;
- V1->y = (V1->y < V2->y) ? V1->y : V2->y;
- V1->z = (V1->z < V2->z) ? V1->z : V2->z;
- }
-
-
- void MaxVector (Vector *V1, Vector *V2)
- {
- V1->x = (V1->x > V2->x) ? V1->x : V2->x;
- V1->y = (V1->y > V2->y) ? V1->y : V2->y;
- V1->z = (V1->z > V2->z) ? V1->z : V2->z;
- }
-
-
- int Degenerate (Triangle *Tri)
- {
- Vector a, b, c;
- Vector ab, bc, Temp;
-
- VectCopy (&a, &Vert[Tri->VertA]);
- VectCopy (&b, &Vert[Tri->VertB]);
- VectCopy (&c, &Vert[Tri->VertC]);
-
- VectSub (&ab, &a, &b);
- VectSub (&bc, &b, &c);
- CrossProd (&Temp, &ab, &bc);
-
- return (VectMag(&Temp) == 0.0);
- }
-
-
- void Read3D2Header()
- {
- int i;
- word Temp;
-
- if (ReadWord(f) != 0x3D02)
- Abort ("Input file is not 3D2 format.", 3);
-
- ObjCount = ReadWord(f);
-
- LightOn[0] = ReadWord(f);
- LightOn[1] = ReadWord(f);
- LightOn[2] = ReadWord(f);
-
- LightBright[0] = ReadWord(f)/7.0;
- LightBright[1] = ReadWord(f)/7.0;
- LightBright[2] = ReadWord(f)/7.0;
-
- Ambient = ReadWord(f)/7.0;
-
- LightPos[0].y = (float)ReadWord(f);
- LightPos[1].y = (float)ReadWord(f);
- LightPos[2].y = (float)ReadWord(f);
-
- LightPos[0].z = (float)ReadWord(f);
- LightPos[1].z = (float)ReadWord(f);
- LightPos[2].z = (float)ReadWord(f);
-
- LightPos[0].x = (float)ReadWord(f);
- LightPos[1].x = (float)ReadWord(f);
- LightPos[2].x = (float)ReadWord(f);
-
- for (i = 0; i < 16; i++) {
- Temp = ReadWord(f);
- Pal[i].Red = ((Temp & 0x0700) >> 8)/7.0;
- Pal[i].Green = ((Temp & 0x0070) >> 4)/7.0;
- Pal[i].Blue = (Temp & 0x0007)/7.0;
- }
-
- for (i = 0; i < 16; i++)
- GBase[i] = ReadWord(f);
-
- PalType = ReadWord(f);
- WColour = ReadWord(f);
- OColour = ReadWord(f);
-
- for (i = 0; i < 150; i++)
- ReadByte(f);
- }
-
-
- void Read3D2Object()
- {
- int i;
-
- for (i = 0; i < 9; i++)
- ObjName[i] = ReadByte(f);
-
- VertCount = ReadWord(f);
-
- Vert = malloc (VertCount * sizeof(*Vert));
- if (Vert == NULL)
- Abort ("Insufficient memory for verticies.", 4);
-
- for (i = 0; i < VertCount; i++) {
- Vert[i].x = ReadWord(f)/100.0;
- Vert[i].z = ReadWord(f)/100.0;
- Vert[i].y = ReadWord(f)/100.0;
- }
-
- TriCount = ReadWord(f);
-
- Tri = malloc (TriCount * sizeof(*Tri));
- if (Tri == NULL)
- Abort ("Insufficient memory for triangles.", 4);
-
- for (i = 0; i < TriCount; i++) {
- Tri[i].VertA = ReadWord(f);
- Tri[i].VertB = ReadWord(f);
- Tri[i].VertC = ReadWord(f);
- Tri[i].EdgeFlag = ReadByte(f);
- Tri[i].Colour = ReadByte(f);
- }
- }
-
-
- void WriteDKBHeader()
- {
- fprintf (g, "{ Converted from file %s with 3D2-DKB %s }\n\n", InFile, Ver);
- fprintf (g, "DECLARE DefaultTexture = TEXTURE\n");
- fprintf (g, " AMBIENT %.3f\n", Ambient);
- fprintf (g, " DIFFUSE 0.7\n");
- fprintf (g, "END_TEXTURE\n\n");
- fprintf (g, "COMPOSITE\n");
- }
-
-
- void BuildTriIndex()
- {
- int Vert, i;
- TriangleNode *Temp;
-
- /* Build a table containing a list of the triangles that use */
- /* each vertex (ie. TriList[n] = List of triangles touching vertex n) */
- TriList = malloc (VertCount * sizeof(TriList));
- if (TriList == NULL)
- Abort ("Insufficient memory for smooth triangles.", 4);
-
- for (i = 0; i < VertCount; i++)
- TriList[i] = NULL;
-
- for (i = 0; i < TriCount; i++) {
- Vert = Tri[i].VertA;
- Temp = TriList[Vert];
- TriList[Vert] = malloc (sizeof (*TriList));
- if (TriList[Vert] == NULL)
- Abort ("Insufficient memory for smooth triangles.", 4);
- TriList[Vert]->TriNo = i;
- TriList[Vert]->Next = Temp;
-
- Vert = Tri[i].VertB;
- Temp = TriList[Vert];
- TriList[Vert] = malloc (sizeof (*TriList));
- if (TriList[Vert] == NULL)
- Abort ("Insufficient memory for smooth triangles.", 4);
- TriList[Vert]->TriNo = i;
- TriList[Vert]->Next = Temp;
-
- Vert = Tri[i].VertC;
- Temp = TriList[Vert];
- TriList[Vert] = malloc (sizeof (*TriList));
- if (TriList[Vert] == NULL)
- Abort ("Insufficient memory for smooth triangles.", 4);
- TriList[Vert]->TriNo = i;
- TriList[Vert]->Next = Temp;
- }
- }
-
-
- void DumpTriIndex()
- {
- int i;
-
- for (i = 0; i < VertCount; i++)
- free (TriList[i]);
-
- free (TriList);
- }
-
-
- void VertNormal (Triangle *T, Vector *NormA, Vector *NormB, Vector *NormC)
- {
- TriangleNode *p;
- Vector Normal, CurrNorm;
-
- VectInit (NormA, 0.0, 0.0, 0.0);
- VectInit (NormB, 0.0, 0.0, 0.0);
- VectInit (NormC, 0.0, 0.0, 0.0);
-
- TriNormal (T, &CurrNorm);
-
- for (p = TriList[T->VertA]; p != NULL; p = p->Next) {
- TriNormal (&Tri[p->TriNo], &Normal);
- if (VectAngle (&CurrNorm, &Normal) < Smooth)
- VectAdd (NormA, NormA, &Normal);
- }
-
- for (p = TriList[T->VertB]; p != NULL; p = p->Next) {
- TriNormal (&Tri[p->TriNo], &Normal);
- if (VectAngle (&CurrNorm, &Normal) < Smooth)
- VectAdd (NormB, NormB, &Normal);
- }
-
- for (p = TriList[T->VertC]; p != NULL; p = p->Next) {
- TriNormal (&Tri[p->TriNo], &Normal);
- if (VectAngle (&CurrNorm, &Normal) < Smooth)
- VectAdd (NormC, NormC, &Normal);
- }
-
- VectScale (NormA, 1.0/VectMag (NormA));
- VectScale (NormB, 1.0/VectMag (NormB));
- VectScale (NormC, 1.0/VectMag (NormC));
- }
-
-
- void TriNormal (Triangle *T, Vector *Normal)
- {
- Vector AB, AC;
- float Mag;
-
- VectSub (&AB, &Vert[T->VertB], &Vert[T->VertA]);
- VectSub (&AC, &Vert[T->VertC], &Vert[T->VertA]);
- CrossProd (Normal, &AC, &AB);
-
- Mag = VectMag (Normal);
- if (Mag > 0.0)
- VectScale (Normal, 1.0/Mag);
- else
- VectInit (Normal, 0.0, 0.0, 0.0);
- }
-
-
- void WriteDKBObject()
- {
- int i, j;
- boolean Start;
- Vector NormA, NormB, NormC;
-
- if (Smooth > 0.0)
- BuildTriIndex();
-
- DegenTri = 0;
-
- for (i = 0; i < 16; i++) {
- Start = false;
- VectInit (&ObjMin, +1e8, +1e8, +1e8);
- VectInit (&ObjMax, -1e8, -1e8, -1e8);
-
- for (j = 0; j < TriCount; j++) {
- if (Tri[j].Colour == i) {
- if (!Start) {
- Start = true;
- fprintf (g, " OBJECT {%s, Pal #%d}\n", ObjName, i);
- fprintf (g, " UNION\n");
- }
-
- if (Degenerate (&Tri[j]))
- ++DegenTri; /* Exclude degenerate triangles */
- else {
- if (Smooth > 0.0) {
- /* Compute vertex normals for smooth triangle */
- VertNormal (&Tri[j], &NormA, &NormB, &NormC);
-
- fprintf (g, " SMOOTH_TRIANGLE ");
- PrintVector (g, &Vert[Tri[j].VertA]);
- PrintVector (g, &NormA);
- PrintVector (g, &Vert[Tri[j].VertB]);
- PrintVector (g, &NormB);
- PrintVector (g, &Vert[Tri[j].VertC]);
- PrintVector (g, &NormC);
- fprintf (g, "END_TRIANGLE\n");
- }
- else {
- fprintf (g, " TRIANGLE ");
- PrintVector (g, &Vert[Tri[j].VertA]);
- PrintVector (g, &Vert[Tri[j].VertB]);
- PrintVector (g, &Vert[Tri[j].VertC]);
- fprintf (g, "END_TRIANGLE\n");
- }
-
- MinVector (&ObjMin, &Vert[Tri[j].VertA]);
- MinVector (&ObjMin, &Vert[Tri[j].VertB]);
- MinVector (&ObjMin, &Vert[Tri[j].VertC]);
-
- MaxVector (&ObjMax, &Vert[Tri[j].VertA]);
- MaxVector (&ObjMax, &Vert[Tri[j].VertB]);
- MaxVector (&ObjMax, &Vert[Tri[j].VertC]);
-
- if (Display)
- PlotTriangle (&Tri[j]);
- }
- }
- }
-
- if (Start) {
- fprintf (g, " END_UNION\n\n");
-
- fprintf (g, " BOUNDED_BY\n");
- fprintf (g, " INTERSECTION\n");
- fprintf (g, " PLANE <+1.0 0.0 0.0> %.2f END_PLANE\n", +ObjMax.x);
- fprintf (g, " PLANE <-1.0 0.0 0.0> %.2f END_PLANE\n", -ObjMin.x);
- fprintf (g, " PLANE <0.0 +1.0 0.0> %.2f END_PLANE\n", +ObjMax.y);
- fprintf (g, " PLANE <0.0 -1.0 0.0> %.2f END_PLANE\n", -ObjMin.y);
- fprintf (g, " PLANE <0.0 0.0 +1.0> %.2f END_PLANE\n", +ObjMax.z);
- fprintf (g, " PLANE <0.0 0.0 -1.0> %.2f END_PLANE\n", -ObjMin.z);
- fprintf (g, " END_INTERSECTION\n");
- fprintf (g, " END_BOUND\n\n");
-
- fprintf (g, " TEXTURE\n");
- fprintf (g, " DefaultTexture\n");
- fprintf (g, " COLOUR RED %.3f GREEN %.3f BLUE %.3f\n",
- Pal[i].Red, Pal[i].Green, Pal[i].Blue);
- fprintf (g, " END_TEXTURE\n");
- fprintf (g, " COLOUR RED %.3f GREEN %.3f BLUE %.3f\n",
- Pal[i].Red, Pal[i].Green, Pal[i].Blue);
-
- fprintf (g, " END_OBJECT {%s, Pal #%d}\n\n", ObjName, i);
- }
- }
-
- if (Smooth > 0.0)
- DumpTriIndex();
-
- free (Vert); /* Free memory used by vertex/triangle lists */
- free (Tri);
- }
-
-
- void WriteDKBSummary()
- {
- Vector Sky, Right, Direction;
- int i;
-
- fprintf (g, "END_COMPOSITE\n\n");
-
- for (i = 0; i < 3; i++) {
- if (LightOn[i]) {
- fprintf (g, "OBJECT\n");
- fprintf (g, " SPHERE <0.0 0.0 0.0> 1.0 END_SPHERE\n");
- fprintf (g, " TRANSLATE <%.2f %.2f %.2f>\n", LightPos[i].x, LightPos[i].y, LightPos[i].z);
- fprintf (g, " TEXTURE\n");
- fprintf (g, " COLOUR RED %.3f GREEN %.3f BLUE %.3f\n",
- LightBright[i], LightBright[i], LightBright[i]);
- fprintf (g, " DIFFUSE 0.0\n");
- fprintf (g, " AMBIENT 1.0\n");
- fprintf (g, " END_TEXTURE\n");
- fprintf (g, " LIGHT_SOURCE\n");
- fprintf (g, " COLOUR RED %.3f GREEN %.3f BLUE %.3f\n",
- LightBright[i], LightBright[i], LightBright[i]);
- fprintf (g, "END_OBJECT\n\n");
- }
- }
-
- VectInit (&Sky, 0.0, 1.0, 0.0);
- VectSub (&Direction, &LookAt, &ViewPoint);
- CrossProd (&Right, &Sky, &Direction);
- VectScale (&Right, 1.33333/VectMag(&Right));
-
- fprintf (g, "VIEW_POINT\n");
- fprintf (g, " LOCATION "); PrintVector (g, &ViewPoint); fprintf (g, "\n");
- fprintf (g, " LOOK_AT "); PrintVector (g, &LookAt); fprintf (g, "\n");
- fprintf (g, " SKY "); PrintVector (g, &Sky); fprintf (g, "\n");
- fprintf (g, " RIGHT "); PrintVector (g, &Right); fprintf (g, "\n");
- fprintf (g, "END_VIEW_POINT\n\n");
- }
-
-
-
- void VectAdd (Vector *V1, Vector *V2, Vector *V3)
- {
- V1->x = V2->x + V3->x;
- V1->y = V2->y + V3->y;
- V1->z = V2->z + V3->z;
- }
-
-
- void VectSub (Vector *V1, Vector *V2, Vector *V3)
- {
- V1->x = V2->x - V3->x;
- V1->y = V2->y - V3->y;
- V1->z = V2->z - V3->z;
- }
-
-
- void VectScale (Vector *V, float k)
- {
- V->x = k*V->x;
- V->y = k*V->y;
- V->z = k*V->z;
- }
-
-
- float VectMag (Vector *V)
- {
- return sqrt((V->x * V->x) + (V->y * V->y) + (V->z * V->z));
- }
-
-
- float DotProd (Vector *V1, Vector *V2)
- {
- return (V1->x*V2->x + V1->y*V2->y + V1->z*V2->z);
- }
-
-
- void CrossProd (Vector *V1, Vector *V2, Vector *V3)
- {
- V1->x = (V2->y * V3->z) - (V2->z * V3->y);
- V1->y = (V2->z * V3->x) - (V2->x * V3->z);
- V1->z = (V2->x * V3->y) - (V2->y * V3->x);
- }
-
-
- void VectCopy (Vector *V1, Vector *V2)
- {
- V1->x = V2->x;
- V1->y = V2->y;
- V1->z = V2->z;
- }
-
-
- void VectInit (Vector *V, float x, float y, float z)
- {
- V->x = x;
- V->y = y;
- V->z = z;
- }
-
-
- float VectAngle (Vector *V1, Vector *V2)
- {
- float Mag1, Mag2, Angle;
-
- Mag1 = VectMag(V1);
- Mag2 = VectMag(V2);
-
- if (Mag1 > 0.0 && Mag2 > 0.0)
- Angle = (180.0/M_PI) * acos(min(1.0, DotProd(V1,V2)/(Mag1 * Mag2)));
- else
- Angle = 0.0;
-
-
- return Angle;
- }
-
-
- void InitDisplay()
- {
- #ifdef __TURBOC__
- int graphdriver = DETECT, graphmode;
-
- Vector Temp;
-
- VectSub (&Nz, &LookAt, &ViewPoint);
- VectScale (&Nz, 1.0/VectMag(&Nz));
-
- VectCopy (&Temp, &Nz);
- VectScale (&Temp, Nz.y/DotProd(&Nz, &Nz));
- VectInit (&Ny, 0.0, 1.0, 0.0);
- VectSub (&Ny, &Ny, &Temp);
- VectScale (&Ny, 1.0/VectMag(&Ny));
-
- CrossProd (&Nx, &Ny, &Nz);
-
- if (Display) {
- initgraph (&graphdriver, &graphmode, "");
- if (graphresult() != grOk) {
- printf ("Error initializing graphics display.\n");
- Display = false;
- }
- }
- #endif
- }
-
-
- void PlotTriangle (Triangle *Tr)
- {
- #ifdef __TURBOC__
- Vector a, b, c, T;
- int ax, ay, bx, by, cx, cy, Shade;
- float rd, gr, bl;
-
- VectCopy (&a, &Vert[Tr->VertA]);
- VectCopy (&b, &Vert[Tr->VertB]);
- VectCopy (&c, &Vert[Tr->VertC]);
-
- VectSub (&a, &a, &ViewPoint);
- T.x = DotProd (&a, &Nx);
- T.y = DotProd (&a, &Ny);
- T.z = DotProd (&a, &Nz);
- VectCopy (&a, &T);
-
- VectSub (&b, &b, &ViewPoint);
- T.x = DotProd (&b, &Nx);
- T.y = DotProd (&b, &Ny);
- T.z = DotProd (&b, &Nz);
- VectCopy (&b, &T);
-
- VectSub (&c, &c, &ViewPoint);
- T.x = DotProd (&c, &Nx);
- T.y = DotProd (&c, &Ny);
- T.z = DotProd (&c, &Nz);
- VectCopy (&c, &T);
-
- /* Don't plot anything that's behind you */
- if (a.z <= 0.0 || b.z <= 0.0 || c.z <= 0.0)
- return;
-
- ax = (0.75*a.x/a.z + 0.5)*getmaxx();
- bx = (0.75*b.x/b.z + 0.5)*getmaxx();
- cx = (0.75*c.x/c.z + 0.5)*getmaxx();
- ay = (0.5 - a.y/a.z)*getmaxy();
- by = (0.5 - b.y/b.z)*getmaxy();
- cy = (0.5 - c.y/c.z)*getmaxy();
-
- Shade = 0;
- bl = Pal[Tr->Colour].Blue;
- gr = Pal[Tr->Colour].Green;
- rd = Pal[Tr->Colour].Red;
- Shade = 1*(bl > 0.3) + 2*(gr > 0.3) + 4*(rd > 0.3) + 8*(bl+gr+rd > 1.5);
-
- if (Shade == 0)
- Shade = 8;
-
- setcolor (Shade);
-
- moveto (ax, ay);
- lineto (bx, by);
- lineto (cx, cy);
- lineto (ax, ay);
- #endif
- }
-
-
- void CloseDisplay()
- {
- #ifdef __TURBOC__
- printf ("Conversion complete.\nPress any key.");
- getch();
- closegraph();
- #endif
- }
-
-